
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>集合增强 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>集合增强 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">使用 Guava 的不可变集合（ImmutableCollection）相比于标准的可变集合有哪些主要优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Guava 不可变集合的主要优势有四个：1. 线程安全，不需要同步；2. 内存效率，通常比可变集合更节省内存；3. 可被安全地用作常量，不会被意外修改；4. 可作为不可信代码的安全返回值，返回内部数据的安全视图。</div>
          </div>
          <div class="card-source">来源: 1.1 为什么需要不可变集合？</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Guava 的 `ImmutableList` 是如何根据集合大小进行性能优化的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ImmutableList 针对不同大小的集合采用不同的实现来优化性能：对于空集合，使用预定义的空集合实例；对于单元素集合，使用专门的 SingletonImmutableList；对于多元素集合，使用 RegularImmutableList。</div>
          </div>
          <div class="card-source">来源: 1.3 以ImmutableList为例分析源码实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在 Guava 中，创建不可变集合（如 ImmutableList）主要有哪三种方式？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">创建 Guava 不可变集合主要有三种方式：1. 使用 of() 方法，适用于元素数量已知且较少的场景；2. 使用 builder() 方法，通过链式调用添加元素后构建；3. 使用 copyOf() 方法，从一个已有的可变集合创建副本。</div>
          </div>
          <div class="card-source">来源: 1.4 构建不可变集合的方式</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Guava 的 MultiMap 是为了解决什么问题而设计的？其内部是如何实现的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">MultiMap 旨在简化一键多值的映射场景（例如一个分类对应多个产品）。其内部实现是使用一个 `Map<K, Collection<V>>` 来存储数据，但对外提供了更简洁的 API，隐藏了手动处理 Collection 的复杂性。</div>
          </div>
          <div class="card-source">来源: 2.1 MultiMap：一键多值的映射</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">Guava 的 BiMap 提供了什么核心功能？它的 `inverse()` 方法有什么作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">BiMap 提供了双向映射功能，即可以在一个数据结构中同时通过键（Key）查找值（Value）以及通过值查找键。它的 `inverse()` 方法会返回一个反向视图（`BiMap<V, K>`），允许用户执行从值到键的查找操作。</div>
          </div>
          <div class="card-source">来源: 2.2 BiMap：双向映射</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">向 BiMap 添加一个已存在的值（Value）会发生什么？如果希望强制添加并覆盖旧的映射关系，应该使用哪个方法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">由于 BiMap 保证键和值都是唯一的，尝试添加一个已存在的值会抛出 IllegalArgumentException。如果希望强制添加，让新的键映射到该值，并移除旧键的映射关系，应该使用 `forcePut(K key, V value)` 方法。</div>
          </div>
          <div class="card-source">来源: 2.2 BiMap：双向映射</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Guava 的 `Collections2.filter()` 和 `Collections2.transform()` 方法在实现上有什么特点，这种设计带来了什么好处？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这两个方法的核心特点是惰性计算（lazy evaluation）。它们不会立即创建一个包含过滤或转换后结果的新集合，而是返回一个集合的视图（View）。好处是在需要迭代访问结果时才进行动态计算，从而节省了内存。</div>
          </div>
          <div class="card-source">来源: 3.1 集合变换的优雅实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">根据文档源码分析，`Collections2.filter()` 是如何实现惰性计算的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Collections2.filter() 的实现返回一个 FilteredCollection 实例，该实例内部持有了原始集合和过滤条件。当调用其 iterator() 方法时，它并不会创建一个新集合，而是返回一个经过 Iterators.filter() 包装的迭代器，这个迭代器在遍历时动态地应用过滤条件。</div>
          </div>
          <div class="card-source">来源: 3.1 集合变换的优雅实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">根据文档，将 Java 集合替换为 Guava 的不可变集合（如 ImmutableMap）后，在性能方面通常会带来哪些具体的提升？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">替换为 Guava 不可变集合后，性能提升主要体现在两个方面：1. 内存占用更少，因为其内部有紧凑的数组表示和对空集合、单元素集合的优化；2. 查询性能更高，因为不可变集合无需担心并发修改，内部实现可以针对只读场景进行优化，避免同步开销。</div>
          </div>
          <div class="card-source">来源: 5. 不可变集合的性能考量</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
